package cn.kgc.utils;

import io.jsonwebtoken.*;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.Date;

/**
 * @author kgc
 */
@Component
public class JwtUtil {

    @Resource
    private JwtProperties jwtProperties;

    /**
     * @param userId    用户信息（token长度限制，最好不要使用整个用户实例，例如可以使用userId）
     * @param loginType 登录类型： {
     *                  app_user(app端的登录 手机号一键注册登录)
     *                  sass_user(用户使用手机扫描二维码登录)
     *                  admin_user(直接使用账号和密码进行登录)
     *                  }
     * @return 令牌
     */
    public String createToken(String userId, String loginType) {
        return Jwts.builder()
                //令牌的发行者
                .setSubject(jwtProperties.getSubject())
                //令牌的过期日期:  从现在开始 + 令牌的过期时间
                .setExpiration(new Date(System.currentTimeMillis() + jwtProperties.getExpiration()))
                //令牌携带的用户信息
                .claim("userId", userId)
                //令牌携带的用户登录方式
                .claim("loginType", loginType)
                //使用秘钥对令牌进行签名
                .signWith(SignatureAlgorithm.HS512, jwtProperties.getSecret())
                .compressWith(CompressionCodecs.GZIP)
                .compact();
    }


    // TODO 三端登录的令牌是同一个，给每一端单独写一个获取令牌和解析令牌的方法

    /**
     * 验证令牌是否正确,并且从令牌中获得登录的用户Id
     *
     * @param token 令牌
     * @return 返回用户的JSON格式的数据
     */
    public String getUserId(String token) throws Exception {
        //使用签名秘钥解析令牌信息
        Jws<Claims> claimsJws = Jwts.parser().setSigningKey(jwtProperties.getSecret()).parseClaimsJws(token);
        //从令牌信息中获得令牌中携带的用户信息
        Claims claims = claimsJws.getBody();
        return (String) claims.get("userId");
    }


    /**
     * 获得用户的登录类型 (哪一端的用户  user_app   admin_app   sass)
     *
     * @param token 令牌
     * @return 返回用户的登录类型
     */
    public String getLoginType(String token) throws Exception {
        //使用签名秘钥解析令牌信息
        Jws<Claims> claimsJws = Jwts.parser().setSigningKey(jwtProperties.getSecret()).parseClaimsJws(token);
        //从令牌信息中获得令牌中携带的用户的ID
        Claims claims = claimsJws.getBody();
        return (String) claims.get("loginType");
    }
}